let slots = [];
// Do this in three parts.
+ let width = 0;
let height = 0;
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
+ width = Math.max(width, row.width);
height += row.height + this._rowSpacing;
}
height -= this._rowSpacing;
+ // If the window layout doesn't fit in the actual
+ // geometry, then apply this additional scale to
+ // tne entire layout.
+ let additionalScale = Math.min(1, area.width / width, area.height / height);
+
let y = 0;
for (let i = 0; i < rows.length; i++) {
let row = rows[i];
- row.x = area.x + (area.width - row.width) / 2;
- row.y = area.y + y + (area.height - height) / 2;
+ row.x = area.x + (Math.max(area.width - row.width, 0) / 2) * additionalScale;
+ row.y = area.y + (y + Math.max(area.height - height, 0) / 2) * additionalScale;
y += row.height + this._rowSpacing;
row.windows.sort(Lang.bind(this, function(a, b) {
for (let j = 0; j < row.windows.length; j++) {
let window = row.windows[j];
- let s = scale * this._computeWindowScale(window);
+ let s = scale * this._computeWindowScale(window) * additionalScale;
let cellWidth = window.actor.width * s;
let cellHeight = window.actor.height * s;
// this, like if the workspace switcher is slid out.
this._fullGeometry = null;
+ // The actual geometry is the geometry we need to arrange windows
+ // in. If this is a smaller area than the full geometry, we'll
+ // do some simple aspect ratio like math to fit the layout calculated
+ // for the full geometry into this area.
+ this._actualGeometry = null;
+
+ this._currentLayout = null;
+
this.monitorIndex = monitorIndex;
this._monitor = Main.layoutManager.monitors[this.monitorIndex];
this._windowOverlaysGroup = new Clutter.Actor();
setFullGeometry: function(geom) {
this._fullGeometry = geom;
+ this._recalculateWindowPositions(WindowPositionFlags.NONE);
+ },
+
+ setActualGeometry: function(geom) {
+ this._actualGeometry = geom;
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
this._dropRect.set_position(geom.x, geom.y);
this._dropRect.set_size(geom.width, geom.height);
+ if (this._currentLayout != null)
+ this._updateWindowPositions(WindowPositionFlags.NONE);
return false;
}));
-
- this._recalculateWindowPositions(WindowPositionFlags.NONE);
},
_lookupIndex: function (metaWindow) {
let strategy = layout.strategy;
let [, , padding] = this._getSpacingAndPadding();
- let area = padArea(this._fullGeometry, padding);
+ let area = padArea(this._actualGeometry, padding);
let slots = strategy.computeWindowSlots(layout, area);
let currentWorkspace = global.screen.get_active_workspace();
}));
this._fullGeometry = null;
+ this._actualGeometry = null;
this._spacing = 0;
this._animating = false; // tweening
let ws = new Workspace.Workspace(null, i);
ws.setFullGeometry(monitors[i]);
+ ws.setActualGeometry(monitors[i]);
global.overlay_group.add_actor(ws.actor);
this._extraWorkspaces.push(ws);
}
this._workspaces[i].setFullGeometry(geom);
},
+ setActualGeometry: function(geom) {
+ if (rectEqual(this._actualGeometry, geom))
+ return;
+
+ this._actualGeometry = geom;
+
+ for (let i = 0; i < this._workspaces.length; i++)
+ this._workspaces[i].setActualGeometry(geom);
+ },
+
_lookupWorkspaceForMetaWindow: function (metaWindow) {
for (let i = 0; i < this._workspaces.length; i++) {
if (this._workspaces[i].containsMetaWindow(metaWindow))
_init: function() {
this.actor = new St.Widget({ clip_to_allocation: true });
+ this.actor.connect('notify::allocation', Lang.bind(this, this._updateWorkspacesActualGeometry));
this.actor.connect('parent-set', Lang.bind(this, this._parentSet));
let clickAction = new Clutter.ClickAction()
}
this._updateWorkspacesFullGeometry();
+ this._updateWorkspacesActualGeometry();
for (let i = 0; i < this._workspacesViews.length; i++)
global.overlay_group.add_actor(this._workspacesViews[i].actor);
}
},
+ _updateWorkspacesActualGeometry: function() {
+ if (!this._workspacesViews.length)
+ return;
+
+ let [x, y] = this.actor.get_transformed_position();
+ let width = this.actor.allocation.x2 - this.actor.allocation.x1;
+ let height = this.actor.allocation.y2 - this.actor.allocation.y1;
+ let geometry = { x: x, y: y, width: width, height: height };
+
+ let monitors = Main.layoutManager.monitors;
+ let m = 0;
+ for (let i = 0; i < monitors.length; i++) {
+ if (i == this._primaryIndex) {
+ this._workspacesViews[m].setActualGeometry(geometry);
+ m++;
+ } else if (!this._workspacesOnlyOnPrimary) {
+ this._workspacesViews[m].setActualGeometry(monitors[i]);
+ m++;
+ }
+ }
+ },
+
_onRestacked: function(overview, stackIndices) {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].syncStacking(stackIndices);